package com.qf.smsplatform.config;
/*2021/11/1*/

import com.qf.smsplatform.mapper.TMenuMapper;
import com.qf.smsplatform.pojo.TMenu;
import com.qf.smsplatform.security.MyFailHandler;
import com.qf.smsplatform.security.MySueecssSecurityHandler;
import com.qf.smsplatform.security.MyUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.util.ObjectUtils;

import java.util.List;

/**
 * @YuTao
 */
@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    private TMenuMapper tMenuMapper;
    @Autowired
    public void settMenuMapper(TMenuMapper tMenuMapper) {
        this.tMenuMapper = tMenuMapper;
    }

    private MySueecssSecurityHandler securityHandler;

    private MyFailHandler myFailHandler;

    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    public void setbCryptPasswordEncoder(BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }
    private MyUserDetailsService myUserDetailsService;
    @Autowired
    public void setMyUserDetailsService(MyUserDetailsService myUserDetailsService) {
        this.myUserDetailsService = myUserDetailsService;
    }

    @Autowired
    public void setMyFailHandler(MyFailHandler myFailHandler) {
        this.myFailHandler = myFailHandler;
    }
    @Autowired
    public void setSecurityHandler(MySueecssSecurityHandler securityHandler) {
        this.securityHandler = securityHandler;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
        //配置了用户的查询方式和密码比较方式
        auth.userDetailsService(myUserDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/","/index.html");//不需要认证即可访问
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();//允许一些跨域请求
        List<TMenu> tMenus = tMenuMapper.selectAll();//拿到数据库中的所有地址和别名
        tMenus.forEach(menu->{
            try {//配置我们的请求地址和数据库中别名之间的关系
                if (!ObjectUtils.isEmpty(menu.getUrl())) {//设置地址权限的时候，判断地址是否为空
                    http.authorizeRequests().antMatchers(menu.getUrl()).hasAnyAuthority(menu.getPerms());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        http.authorizeRequests().anyRequest().authenticated()//上面设置了每个地址的具体配置，有可能有些地址还没在数据库中表中，然后默认这些地址必须要登录才能访问
                .and().formLogin().loginProcessingUrl("/login")//设置我们登录的地址
                .permitAll()//设置我们登录的接口是login,springsecurity 会自动生成这个接口//permitAll放行登录的地址
                .successHandler(securityHandler)
                .failureHandler(myFailHandler)
                .and().logout().logoutUrl("/logout");//设置退出的地址时logout
//              LogoutSuccessHandler
    }
}
